package edu.siu.math.egut.egut;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;



/**
 * Static algorithms that don't fit (logically) in any other class.
 * @author Joe Pleso
 *
 */
 final class Algorithms {
	
	
    
    /**
     * 
     */
    public static final char LIE_UNDERSCORE = '_';
    /**
     * 
     */
    public static final char LIE_PLUS = '+';
    /**
     * 
     */
    public static final char LIE_X = 'X';
    /**
     * 
     */
    public static final char LIE_MINUS = '-';
    /**
     * 
     */
    public static final char LIE_LEFT_PARENTHESIS = '(';
    /**
     * 
     */
    public  static final char LIE_RIGHT_PARENTHESIS = ')';
    /**
     * 
     */
    public static final char LIE_COMMA = ',';
    /**
     * 
     */
    public static final char LIE_LEFT_SQUARE_BRACKET = '[';
    /**
     * 
     */
    public static final char LIE_RIGHT_SQUARE_BRACKET = ']';
    /**
     * 
     */
    public static final char LIE_SPACE = ' ';
    /**
     * 
     */
    public static final char LIE_NEWLINE = '\n';
    /**
     * 
     */
    public static final char LIE_QUOTE = '\"';
    /**
     * 
     */
    public static final char LIE_BACKSLASH = '\\';
    /**
     * 
     */
    public static final String LIE_PRINT_COMMAND = "print";
    /**
     * 
     */
    public static final char LIE_PROMPT_1 = '>';
    /**
     * 
     */
    public static final char LIE_PROMPT_2 = '\\';
    /**
     * 
     */
    public static final String LIE_PARTING_MESSAGE = "end program";
    
    /**
     * 
     */
    public static final char LIE_COMMENT = '#';
    /**
     * 
     */
    public static final String LIE_DEFAULT_GROUP_FUNCTION = 
	"default";
    /**
     * 
     */
    public static final String LIE_DEFAULT_GROUP_FUNCTION_DEFINITION = 
	LIE_DEFAULT_GROUP_FUNCTION + "(grp g)=g";
    /**
     * 
     */
    public static final char LIE_N = 'N';
    

    
    
	private Algorithms(){
		
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * Starts a new instance of LiE and returns its process.
	 * 
	 * @param redirect specifies if stderr should be 
	 * redirected to stdout for the
	 * LiE process 
	 * 
	 * @return a new process that is running LiE
	 */
	static public Process getNewLiEProcess(boolean redirect){
	    ProcessBuilder proc = new ProcessBuilder("lie");
	    proc.redirectErrorStream(redirect);
	    try {
		return proc.start();
	    } catch (IOException e) {


		e.printStackTrace();
		return null;
	    }
	}
	
	/**
	 * Run the specified LiE command and return the result.
	     * @param cmd the command to be run in LiE
	     * @return the result of the LiE command
	 *  
	  
	     */
	    static public String[] runLiECommand(String cmd) 
	        
	    {  

	    
		String[] result = new String[2];
		Process proc = getNewLiEProcess(false);
		    

	     

	           
	            
	            InputStream in = proc.getInputStream(); 
	            OutputStream out = proc.getOutputStream();
	            
	            BufferedWriter bin = new BufferedWriter(
	        	    new OutputStreamWriter(out));
	            BufferedReader bout = new BufferedReader(
	        	    new InputStreamReader(in));
	            BufferedReader berr = new BufferedReader(
	        	    new InputStreamReader(proc.getErrorStream()));
	            
	            StringBuffer str = new StringBuffer();
	            
	            
	            try {
	        	bin.write(cmd);
	        	bin.newLine();
			bin.close();
			String s = bout.readLine();
			while (s!=null){
			    str.append(s);
			    s = bout.readLine();
			}
			result[0] = str.toString();
			str = new StringBuffer();
			s = berr.readLine();
			while (s != null){
			    str.append(s);
			    s = berr.readLine();
			}
			result[1] = str.toString();
			    
			proc.waitFor();
			return result;
			
		    } catch (IOException e) {
			
			e.printStackTrace();
			return null;
		    } catch (InterruptedException e) {
			
			e.printStackTrace();
			return null;
		    }finally{
			try {
			    berr.close();
			    bout.close();
				bin.close();
			} catch (IOException e) {
		
			    e.printStackTrace();
			}
			
		    }
	           
	            
	           
	            
	        	
	           
	         


	            
	        }
	

	/**
	 * Converts an array of LiEType into a string.
	 * 
	 * @param argList the array to be converted
	 * @return the string representation of the specified array
	 */
	public static String argList(LiEType[] argList) {

	    StringBuffer sb = new StringBuffer();
	    sb.append(LIE_LEFT_PARENTHESIS);
	    for (int i = 0; i < argList.length; i++){
		sb.append(argList[i].getName() + LIE_COMMA + LIE_SPACE);
	    }
	    return sb.substring(0, sb.length() - 1) + LIE_RIGHT_PARENTHESIS;

	}
}
	

